home *** CD-ROM | disk | FTP | other *** search
/ Aminet 49 / Aminet 49 (2002)(GTI - Schatztruhe)[!][Jun 2002].iso / Aminet / util / libs / ttrender.lha / ttrender-2.0 / Developer / source / sfnt / ttpost.c < prev    next >
Encoding:
C/C++ Source or Header  |  2002-04-06  |  15.2 KB  |  535 lines

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ttpost.c                                                               */
  4. /*                                                                         */
  5. /*    Postcript name table processing for TrueType and OpenType fonts      */
  6. /*    (body).                                                              */
  7. /*                                                                         */
  8. /*  Copyright 1996-2001 by                                                 */
  9. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  10. /*                                                                         */
  11. /*  This file is part of the FreeType project, and may only be used,       */
  12. /*  modified, and distributed under the terms of the FreeType project      */
  13. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  14. /*  this file you indicate that you have read the license and              */
  15. /*  understand and accept it fully.                                        */
  16. /*                                                                         */
  17. /***************************************************************************/
  18.  
  19.   /*************************************************************************/
  20.   /*                                                                       */
  21.   /* The post table is not completely loaded by the core engine.  This     */
  22.   /* file loads the missing PS glyph names and implements an API to access */
  23.   /* them.                                                                 */
  24.   /*                                                                       */
  25.   /*************************************************************************/
  26.  
  27.  
  28. #include <ft2build.h>
  29. #include FT_INTERNAL_STREAM_H
  30. #include FT_TRUETYPE_TAGS_H
  31. #include "ttpost.h"
  32. #include "ttload.h"
  33.  
  34. #include "sferrors.h"
  35.  
  36.   /*************************************************************************/
  37.   /*                                                                       */
  38.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  39.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  40.   /* messages during execution.                                            */
  41.   /*                                                                       */
  42. #undef  FT_COMPONENT
  43. #define FT_COMPONENT  trace_ttpost
  44.  
  45.  
  46.   /* If this configuration macro is defined, we rely on the `PSNames' */
  47.   /* module to grab the glyph names.                                  */
  48.  
  49. #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
  50.  
  51.  
  52. #include <freetype/internal/psnames.h>
  53.  
  54. #define MAC_NAME( x )  ( (FT_String*)psnames->macintosh_name( x ) )
  55.  
  56.  
  57. #else /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
  58.  
  59.  
  60.    /* Otherwise, we ignore the `PSNames' module, and provide our own  */
  61.    /* table of Mac names.  Thus, it is possible to build a version of */
  62.    /* FreeType without the Type 1 driver & PSNames module.            */
  63.  
  64. #define MAC_NAME( x )  TT_Post_Default_Names[x]
  65.  
  66.   /* the 258 default Mac PS glyph names */
  67.  
  68.   FT_String*  TT_Post_Default_Names[258] =
  69.   {
  70.     /*   0 */
  71.     ".notdef", ".null", "CR", "space", "exclam",
  72.     "quotedbl", "numbersign", "dollar", "percent", "ampersand",
  73.     /*  10 */
  74.     "quotesingle", "parenleft", "parenright", "asterisk", "plus",
  75.     "comma", "hyphen", "period", "slash", "zero",
  76.     /*  20 */
  77.     "one", "two", "three", "four", "five",
  78.     "six", "seven", "eight", "nine", "colon",
  79.     /*  30 */
  80.     "semicolon", "less", "equal", "greater", "question",
  81.     "at", "A", "B", "C", "D",
  82.     /*  40 */
  83.     "E", "F", "G", "H", "I",
  84.     "J", "K", "L", "M", "N",
  85.     /*  50 */
  86.     "O", "P", "Q", "R", "S",
  87.     "T", "U", "V", "W", "X",
  88.     /*  60 */
  89.     "Y", "Z", "bracketleft", "backslash", "bracketright",
  90.     "asciicircum", "underscore", "grave", "a", "b",
  91.     /*  70 */
  92.     "c", "d", "e", "f", "g",
  93.     "h", "i", "j", "k", "l",
  94.     /*  80 */
  95.     "m", "n", "o", "p", "q",
  96.     "r", "s", "t", "u", "v",
  97.     /*  90 */
  98.     "w", "x", "y", "z", "braceleft",
  99.     "bar", "braceright", "asciitilde", "Adieresis", "Aring",
  100.     /* 100 */
  101.     "Ccedilla", "Eacute", "Ntilde", "Odieresis", "Udieresis",
  102.     "aacute", "agrave", "acircumflex", "adieresis", "atilde",
  103.     /* 110 */
  104.     "aring", "ccedilla", "eacute", "egrave", "ecircumflex",
  105.     "edieresis", "iacute", "igrave", "icircumflex", "idieresis",
  106.     /* 120 */
  107.     "ntilde", "oacute", "ograve", "ocircumflex", "odieresis",
  108.     "otilde", "uacute", "ugrave", "ucircumflex", "udieresis",
  109.     /* 130 */
  110.     "dagger", "degree", "cent", "sterling", "section",
  111.     "bullet", "paragraph", "germandbls", "registered", "copyright",
  112.     /* 140 */
  113.     "trademark", "acute", "dieresis", "notequal", "AE",
  114.     "Oslash", "infinity", "plusminus", "lessequal", "greaterequal",
  115.     /* 150 */
  116.     "yen", "mu", "partialdiff", "summation", "product",
  117.     "pi", "integral", "ordfeminine", "ordmasculine", "Omega",
  118.     /* 160 */
  119.     "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
  120.     "radical", "florin", "approxequal", "Delta", "guillemotleft",
  121.     /* 170 */
  122.     "guillemotright", "ellipsis", "nbspace", "Agrave", "Atilde",
  123.     "Otilde", "OE", "oe", "endash", "emdash",
  124.     /* 180 */
  125.     "quotedblleft", "quotedblright", "quoteleft", "quoteright", "divide",
  126.     "lozenge", "ydieresis", "Ydieresis", "fraction", "currency",
  127.     /* 190 */
  128.     "guilsinglleft", "guilsinglright", "fi", "fl", "daggerdbl",
  129.     "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", "Acircumflex",
  130.     /* 200 */
  131.     "Ecircumflex", "Aacute", "Edieresis", "Egrave", "Iacute",
  132.     "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",
  133.     /* 210 */
  134.     "apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave",
  135.     "dotlessi", "circumflex", "tilde", "macron", "breve",
  136.     /* 220 */
  137.     "dotaccent", "ring", "cedilla", "hungarumlaut", "ogonek",
  138.     "caron", "Lslash", "lslash", "Scaron", "scaron",
  139.     /* 230 */
  140.     "Zcaron", "zcaron", "brokenbar", "Eth", "eth",
  141.     "Yacute", "yacute", "Thorn", "thorn", "minus",
  142.     /* 240 */
  143.     "multiply", "onesuperior", "twosuperior", "threesuperior", "onehalf",
  144.     "onequarter", "threequarters", "franc", "Gbreve", "gbreve",
  145.     /* 250 */
  146.     "Idot", "Scedilla", "scedilla", "Cacute", "cacute",
  147.     "Ccaron", "ccaron", "dmacron",
  148.   };
  149.  
  150.  
  151. #endif /* FT_CONFIG_OPTION_POSTSCRIPT_NAMES */
  152.  
  153.  
  154.   static FT_Error
  155.   Load_Format_20( TT_Face    face,
  156.                   FT_Stream  stream )
  157.   {
  158.     FT_Memory  memory = stream->memory;
  159.     FT_Error   error;
  160.  
  161.     FT_Int     num_glyphs;
  162.     FT_UShort  num_names;
  163.  
  164.     FT_UShort* glyph_indices = 0;
  165.     FT_Char**  name_strings  = 0;
  166.  
  167.  
  168.     if ( READ_UShort( num_glyphs ) )
  169.       goto Exit;
  170.  
  171.     /* UNDOCUMENTED!  The number of glyphs in this table can be smaller */
  172.     /* than the value in the maxp table (cf. cyberbit.ttf).             */
  173.  
  174.     /* There already exist fonts which have more than 32768 glyph names */
  175.     /* in this table, so the test for this threshold has been dropped.  */
  176.  
  177.     if ( num_glyphs > face->root.num_glyphs )
  178.     {
  179.       error = SFNT_Err_Invalid_File_Format;
  180.       goto Exit;
  181.     }
  182.  
  183.     /* load the indices */
  184.     {
  185.       FT_Int  n;
  186.  
  187.  
  188.       if ( ALLOC_ARRAY ( glyph_indices, num_glyphs, FT_UShort ) ||
  189.            ACCESS_Frame( num_glyphs * 2L )                      )
  190.         goto Fail;
  191.  
  192.       for ( n = 0; n < num_glyphs; n++ )
  193.         glyph_indices[n] = GET_UShort();
  194.  
  195.       FORGET_Frame();
  196.     }
  197.  
  198.     /* compute number of names stored in table */
  199.     {
  200.       FT_Int  n;
  201.  
  202.  
  203.       num_names = 0;
  204.  
  205.       for ( n = 0; n < num_glyphs; n++ )
  206.       {
  207.         FT_Int  index;
  208.  
  209.  
  210.         index = glyph_indices[n];
  211.         if ( index >= 258 )
  212.         {
  213.           index -= 257;
  214.           if ( index > num_names )
  215.             num_names = (FT_UShort)index;
  216.         }
  217.       }
  218.     }
  219.  
  220.     /* now load the name strings */
  221.     {
  222.       FT_UShort  n;
  223.  
  224.  
  225.       if ( ALLOC_ARRAY( name_strings, num_names, FT_Char* ) )
  226.         goto Fail;
  227.  
  228.       for ( n = 0; n < num_names; n++ )
  229.       {
  230.         FT_UInt  len;
  231.  
  232.  
  233.         if ( READ_Byte  ( len )                               ||
  234.              ALLOC_ARRAY( name_strings[n], len + 1, FT_Char ) ||
  235.              FILE_Read  ( name_strings[n], len )              )
  236.           goto Fail1;
  237.  
  238.         name_strings[n][len] = '\0';
  239.       }
  240.     }
  241.  
  242.     /* all right, set table fields and exit successfuly */
  243.     {
  244.       TT_Post_20*  table = &face->postscript_names.names.format_20;
  245.  
  246.  
  247.       table->num_glyphs    = (FT_UShort)num_glyphs;
  248.       table->num_names     = (FT_UShort)num_names;
  249.       table->glyph_indices = glyph_indices;
  250.       table->glyph_names   = name_strings;
  251.     }
  252.     return SFNT_Err_Ok;
  253.  
  254.  
  255.   Fail1:
  256.     {
  257.       FT_UShort  n;
  258.  
  259.  
  260.       for ( n = 0; n < num_names; n++ )
  261.         FREE( name_strings[n] );
  262.     }
  263.  
  264.   Fail:
  265.     FREE( name_strings );
  266.     FREE( glyph_indices );
  267.  
  268.   Exit:
  269.     return error;
  270.   }
  271.  
  272.  
  273.   static FT_Error
  274.   Load_Format_25( TT_Face    face,
  275.                   FT_Stream  stream )
  276.   {
  277.     FT_Memory  memory = stream->memory;
  278.     FT_Error   error;
  279.  
  280.     FT_Int     num_glyphs;
  281.     FT_Char*   offset_table = 0;
  282.  
  283.  
  284.     /* UNDOCUMENTED!  This value appears only in the Apple TT specs. */
  285.     if ( READ_UShort( num_glyphs ) )
  286.       goto Exit;
  287.  
  288.     /* check the number of glyphs */
  289.     if ( num_glyphs > face->root.num_glyphs || num_glyphs > 258 )
  290.     {
  291.       error = SFNT_Err_Invalid_File_Format;
  292.       goto Exit;
  293.     }
  294.  
  295.     if ( ALLOC    ( offset_table, num_glyphs ) ||
  296.          FILE_Read( offset_table, num_glyphs ) )
  297.       goto Fail;
  298.  
  299.     /* now check the offset table */
  300.     {
  301.       FT_Int  n;
  302.  
  303.  
  304.       for ( n = 0; n < num_glyphs; n++ )
  305.       {
  306.         FT_Long  index = (FT_Long)n + offset_table[n];
  307.  
  308.  
  309.         if ( index < 0 || index > num_glyphs )
  310.         {
  311.           error = SFNT_Err_Invalid_File_Format;
  312.           goto Fail;
  313.         }
  314.       }
  315.     }
  316.  
  317.     /* OK, set table fields and exit successfuly */
  318.     {
  319.       TT_Post_25*  table = &face->postscript_names.names.format_25;
  320.  
  321.  
  322.       table->num_glyphs = (FT_UShort)num_glyphs;
  323.       table->offsets    = offset_table;
  324.     }
  325.  
  326.     return SFNT_Err_Ok;
  327.  
  328.   Fail:
  329.     FREE( offset_table );
  330.  
  331.   Exit:
  332.     return error;
  333.   }
  334.  
  335.  
  336.   static FT_Error
  337.   Load_Post_Names( TT_Face  face )
  338.   {
  339.     FT_Stream  stream;
  340.     FT_Error   error;
  341.     FT_Fixed   format;
  342.  
  343.  
  344.     /* get a stream for the face's resource */
  345.     stream = face->root.stream;
  346.  
  347.     /* seek to the beginning of the PS names table */
  348.     error = face->goto_table( face, TTAG_post, stream, 0 );
  349.     if ( error )
  350.       goto Exit;
  351.  
  352.     format = face->postscript.FormatType;
  353.  
  354.     /* go to beginning of subtable */
  355.     if ( FILE_Skip( 32 ) )
  356.       goto Exit;
  357.  
  358.     /* now read postscript table */
  359.     switch ( format )
  360.     {
  361.     case 0x00020000L:
  362.       error = Load_Format_20( face, stream );
  363.       break;
  364.  
  365.     case 0x00028000L:
  366.       error = Load_Format_25( face, stream );
  367.       break;
  368.  
  369.     default:
  370.       error = SFNT_Err_Invalid_File_Format;
  371.     }
  372.  
  373.     face->postscript_names.loaded = 1;
  374.  
  375.   Exit:
  376.     return error;
  377.   }
  378.  
  379.  
  380.   FT_LOCAL_DEF void
  381.   TT_Free_Post_Names( TT_Face  face )
  382.   {
  383.     FT_Memory       memory = face->root.memory;
  384.     TT_Post_Names*  names  = &face->postscript_names;
  385.  
  386.  
  387.     if ( names->loaded )
  388.     {
  389.       switch ( face->postscript.FormatType )
  390.       {
  391.       case 0x00020000L:
  392.         {
  393.           TT_Post_20*  table = &names->names.format_20;
  394.           FT_UShort    n;
  395.  
  396.  
  397.           FREE( table->glyph_indices );
  398.           table->num_glyphs = 0;
  399.  
  400.           for ( n = 0; n < table->num_names; n++ )
  401.             FREE( table->glyph_names[n] );
  402.  
  403.           FREE( table->glyph_names );
  404.           table->num_names = 0;
  405.         }
  406.         break;
  407.  
  408.       case 0x00028000L:
  409.         {
  410.           TT_Post_25*  table = &names->names.format_25;
  411.  
  412.  
  413.           FREE( table->offsets );
  414.           table->num_glyphs = 0;
  415.         }
  416.         break;
  417.       }
  418.     }
  419.     names->loaded = 0;
  420.   }
  421.  
  422.  
  423.   /*************************************************************************/
  424.   /*                                                                       */
  425.   /* <Function>                                                            */
  426.   /*    TT_Get_PS_Name                                                     */
  427.   /*                                                                       */
  428.   /* <Description>                                                         */
  429.   /*    Gets the PostScript glyph name of a glyph.                         */
  430.   /*                                                                       */
  431.   /* <Input>                                                               */
  432.   /*    face   :: A handle to the parent face.                             */
  433.   /*                                                                       */
  434.   /*    index  :: The glyph index.                                         */
  435.   /*                                                                       */
  436.   /*    PSname :: The address of a string pointer.  Will be NULL in case   */
  437.   /*              of error, otherwise it is a pointer to the glyph name.   */
  438.   /*                                                                       */
  439.   /*              You must not modify the returned string!                 */
  440.   /*                                                                       */
  441.   /* <Output>                                                              */
  442.   /*    FreeType error code.  0 means success.                             */
  443.   /*                                                                       */
  444.   FT_LOCAL_DEF FT_Error
  445.   TT_Get_PS_Name( TT_Face      face,
  446.                   FT_UInt      index,
  447.                   FT_String**  PSname )
  448.   {
  449.     FT_Error            error;
  450.     TT_Post_Names*      names;
  451.  
  452. #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
  453.     PSNames_Interface*  psnames;
  454. #endif
  455.  
  456.  
  457.     if ( !face )
  458.       return SFNT_Err_Invalid_Face_Handle;
  459.  
  460.     if ( index >= (FT_UInt)face->root.num_glyphs )
  461.       return SFNT_Err_Invalid_Glyph_Index;
  462.  
  463. #ifdef FT_CONFIG_OPTION_POSTSCRIPT_NAMES
  464.     psnames = (PSNames_Interface*)face->psnames;
  465.     if ( !psnames )
  466.       return SFNT_Err_Unimplemented_Feature;
  467. #endif
  468.  
  469.     names = &face->postscript_names;
  470.  
  471.     /* `.notdef' by default */
  472.     *PSname = MAC_NAME( 0 );
  473.  
  474.     switch ( face->postscript.FormatType )
  475.     {
  476.     case 0x00010000L:
  477.       if ( index < 258 )                    /* paranoid checking */
  478.         *PSname = MAC_NAME( index );
  479.       break;
  480.  
  481.     case 0x00020000L:
  482.       {
  483.         TT_Post_20*  table = &names->names.format_20;
  484.  
  485.  
  486.         if ( !names->loaded )
  487.         {
  488.           error = Load_Post_Names( face );
  489.           if ( error )
  490.             break;
  491.         }
  492.  
  493.         if ( index < (FT_UInt)table->num_glyphs )
  494.         {
  495.           FT_UShort  name_index = table->glyph_indices[index];
  496.  
  497.  
  498.           if ( name_index < 258 )
  499.             *PSname = MAC_NAME( name_index );
  500.           else
  501.             *PSname = (FT_String*)table->glyph_names[name_index - 258];
  502.         }
  503.       }
  504.       break;
  505.  
  506.     case 0x00028000L:
  507.       {
  508.         TT_Post_25*  table = &names->names.format_25;
  509.  
  510.  
  511.         if ( !names->loaded )
  512.         {
  513.           error = Load_Post_Names( face );
  514.           if ( error )
  515.             break;
  516.         }
  517.  
  518.         if ( index < (FT_UInt)table->num_glyphs )    /* paranoid checking */
  519.         {
  520.           index  += table->offsets[index];
  521.           *PSname = MAC_NAME( index );
  522.         }
  523.       }
  524.       break;
  525.  
  526.     case 0x00030000L:
  527.       break;                                /* nothing to do */
  528.     }
  529.  
  530.     return SFNT_Err_Ok;
  531.   }
  532.  
  533.  
  534. /* END */
  535.